package com.haredot.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.haredot.config.JwtConfig;
import com.haredot.entity.User;

import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Map;

public class JwtUtils {

    /**
     * 获取  JWT 访问令牌
     */
    public static Map<String, Object> generatorJwtAccessToken(User user) {

        Instant now = Instant.now();
        // 获取签发时间戳
        long issTime = now.getEpochSecond();

        Instant expired = Instant.now().plus(Duration.ofMinutes(JwtConfig.ACCESS_TOKEN_EXPIRED_TIME_IN_MIN));
        // 获取 过期时间
        long expiredTime = expired.getEpochSecond();

        // 生成 JWT 唯一标识  （name + 签发时间 +  过期时间）
        String identify = MessageFormat.format("{0}:{1}:{2}", user.getName(), String.valueOf(issTime), String.valueOf(expiredTime)) ;

        String accessToken = JWT.create()
                .withJWTId(Base64.getEncoder().encodeToString(identify.getBytes(StandardCharsets.UTF_8)))
                .withIssuer(JwtConfig.ISSUER)
                .withSubject(String.valueOf(user.getId()))
                .withClaim("name", user.getName())
                .withExpiresAt(expired)
                .withAudience("ALL")
                .withIssuedAt(now)
                .sign(Algorithm.HMAC256(JwtConfig.SECURE_KEY));

        // 准备返回数据
        return Map.of("accessToken", accessToken,
                "accessExpire", Duration.of(JwtConfig.ACCESS_TOKEN_EXPIRED_TIME_IN_MIN, ChronoUnit.MINUTES).toSeconds()) ;

    }


    public static Map<String, Object> generatorJwtRefreshToken(User user) {

        Instant now = Instant.now();
        // 获取签发时间戳
        long issTime = now.getEpochSecond();

        Instant expired = Instant.now().plus(Duration.ofDays(JwtConfig.REFRESH_TOKEN_EXPIRED_TIME_IN_DAY));
        // 获取 过期时间
        long expiredTime = expired.getEpochSecond();

        // 生成 JWT 唯一标识  base64（name + 签发时间 +  过期时间 + MD5(name + 签发时间 +  过期时间 + 密码 + KEY)）
        String identify = MessageFormat.format("{0}:{1}:{2}:{3}:{4}", user.getName(), String.valueOf(issTime), String.valueOf(expiredTime), user.getPassword() , JwtConfig.SECURE_KEY) ;

        String identify_text =  MessageFormat.format("{0}:{1}:{2}:{3}", user.getName(), String.valueOf(issTime), String.valueOf(expiredTime), MD5Utils.md5(identify)) ;

        String refreshToken = JWT.create()
                .withJWTId(Base64.getEncoder().encodeToString(identify_text.getBytes(StandardCharsets.UTF_8)))
                .withIssuer(JwtConfig.ISSUER)
                .withSubject(String.valueOf(user.getId()))
                .withClaim("name", user.getName())
                .withExpiresAt(expired)
                .withAudience("ALL")
                .withIssuedAt(now)
                .sign(Algorithm.HMAC256(JwtConfig.SECURE_KEY));

        // 准备返回数据
        return Map.of("refreshToken", refreshToken,
                "refreshExpire", Duration.of(JwtConfig.REFRESH_TOKEN_EXPIRED_TIME_IN_DAY, ChronoUnit.DAYS).toSeconds()) ;

    }

    /**
     * 验证令牌
     */
    public static DecodedJWT checkToken(String token) {
        return JWT.require(Algorithm.HMAC256(JwtConfig.SECURE_KEY))
                .build()
                .verify(token);
    }


    public static void main(String[] args) {
        System.out.println(LocalDateTime.now());
    }
}
